package com.taiguan.eis.solution.eiswebservice.serviceimpl;

import lombok.extern.slf4j.Slf4j;
import org.jdom.Element;
import org.jdom.input.SAXBuilder;
import org.jdom.output.XMLOutputter;
import org.jdom.xpath.XPath;
import org.springframework.amqp.core.Message;
import org.springframework.amqp.core.MessageProperties;
import org.springframework.amqp.rabbit.connection.CorrelationData;
import org.springframework.amqp.rabbit.core.RabbitTemplate;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.jdom.Document;
import org.springframework.util.StringUtils;

import java.io.StringReader;
import java.nio.charset.Charset;
import java.util.HashMap;
import java.util.Map;
import java.util.UUID;


@Slf4j
@Service
public class SenderService {
    @Autowired
    private RabbitTemplate rabbitTemplate;

    public String SendRequest(String msg){
        log.info("build and send--------------------------------------- ");
        log.info(msg);
        MessageProperties mp = new MessageProperties();
        mp.setCorrelationId(UUID.randomUUID().toString());
        mp.setExpiration("60000");
        Message newMessage = new Message(msg.getBytes(Charset.forName("UTF-8")),mp);
        CorrelationData correlationData = new CorrelationData(UUID.randomUUID().toString());
        Object response = rabbitTemplate.sendAndReceive("MES.PRD.SVR", "MES.PRD.OIC.CNX", newMessage,correlationData);
        Document document = null;
        String result ="";
        if(response instanceof Message){
            document = getDocumentFromAmqpMessage((Message) response);
            if(document == null){
                log.info("Received Message : " + response.toString());
                log.error("Received Message can not be parsed, MQ Message Field type should be \"Message\"  and Message content should be Xml String "  );
                return "";
            }
            else {
                try {
                    log.info("Received Message : " + response.toString());
                    Element root = document.getRootElement();//获得根元素element
                    Element returnElement = root.getChild("Return");

                    String returnCode =returnElement.getChildText("RETURNCODE");
                    if(returnCode.equals("0")){
                        result = returnCode;
                    }else {
                        String returnText = returnElement.getChildText("RETURNMESSAGE");
                        result = returnCode +'|' +returnText;
                    }
                    log.info("Result  : "+result);
                } catch (Exception e) {
                    e.printStackTrace();
                }
            }
        }
        return result;
    }

    public static Document getDocumentFromAmqpMessage(org.springframework.amqp.core.Message message) {
        Document document = null;
        Object obj = null;

        try {
            obj = message.getBody();
            if (obj instanceof String) {
                document = new SAXBuilder().build(new StringReader(((String)obj)));
            } else if (obj instanceof Document) {
                document = (Document)obj;
            } else {
                if (!(obj instanceof byte[])) {
                    log.warn("Could not convert xml.document type, because input data is not string");
                    return null;
                }

                if (message.getMessageProperties().getContentEncoding() != null) {
                    //document = JdomUtils.loadText(new String((byte[])((byte[])obj), message.getMessageProperties().getContentEncoding()));
                    String text = new String((byte[])((byte[])obj), message.getMessageProperties().getContentEncoding());
                    document = (new SAXBuilder()).build(new StringReader(text));
                } else {
                    document = new SAXBuilder().build(new StringReader((new String(((byte[])obj)))));
                }
            }
        } catch (Exception var7) {
            try {
                if (obj instanceof String) {
                    document = createXmlDocument((String)obj);
                }
            } catch (Exception var6) {
                log.error(String.valueOf(var6), var6);
                return null;
            }
        }

        return document;
    }

    private static Document createXmlDocument(String receivedData) throws Exception {
        Element root = new Element("Message");
        Document document = new Document(root);
        int idx = receivedData.indexOf(" ");
        String commandName = receivedData.substring(0, idx).trim();
        Map<String, String> messageMap = null;
        messageMap = parsingStringMessage(receivedData);
        Element header = new Element("Header");
        Element subElement = new Element("MESSAGENAME");
        subElement.setText(commandName);
        header.addContent(subElement);
        subElement = new Element("COMMAND");
        subElement.setText(commandName);
        header.addContent(subElement);
        root.addContent(header);
        Element body = new Element("Body");
        Element ele = null;

        while(messageMap.keySet().iterator().hasNext()) {
            String keyName = (String)messageMap.keySet().iterator().next();
            String keyValue = (String)messageMap.remove(keyName);
            ele = new Element(keyName);
            ele.setText(keyValue);
            body.addContent(ele);
        }

        root.addContent(body);
        messageMap.clear();
        //log.debug(JdomUtils.toString(document));
        return document;
    }

    private static Map parsingStringMessage(String msg) {
        String delimeter = "[{X*X}]";
        String msg2 = msg;

        while(true) {
            int idx1 = msg2.indexOf("=[");
            int idx2 = msg2.indexOf("]", idx1);
            if (idx1 <= 0 || idx2 <= 0) {
                String[] messageSplit = msg.split("=");
                Map<String, String> params = new HashMap();
                StringBuffer keyNameBuffer = new StringBuffer();
                keyNameBuffer.append("COMMAND").append(delimeter);
                StringBuffer valueBuffer = new StringBuffer();

                for(int i = 0; i < messageSplit.length; ++i) {
                    if (getKeyName(messageSplit[i]).length() > 0) {
                        keyNameBuffer.append(getKeyName(messageSplit[i])).append(delimeter);
                        valueBuffer.append(getValue(messageSplit[i])).append(delimeter);
                    } else {
                        valueBuffer.append(messageSplit[i]).append(delimeter);
                    }
                }

                String[] keyNames = StringUtils.delimitedListToStringArray(keyNameBuffer.toString(), delimeter);
                String[] keyvalues = StringUtils.delimitedListToStringArray(valueBuffer.toString(), delimeter);

                for(int i = 1; i < keyNames.length; ++i) {
                    if (keyNames[i] != null && keyNames[i].trim().length() != 0) {
                        try {
                            keyvalues[i] = keyvalues[i].trim();
                            keyvalues[i] = StringUtils.replace(keyvalues[i], "($%^)", "=");
                            if (keyvalues[i].startsWith("[") && keyvalues[i].endsWith("]")) {
                                keyvalues[i] = keyvalues[i].substring(1, keyvalues[i].length() - 1);
                            }

                            params.put(keyNames[i], keyvalues[i].trim());
                        } catch (Exception var11) {
                            params.put(keyNames[i], "");
                            log.debug("Value of last data is empty");
                        }
                    }
                }

                return params;
            }

            String a = msg2.substring(idx1 + 2, idx2);
            if (a.length() == 0) {
                msg2 = msg2.substring(idx2 + 1, msg2.length());
            } else {
                String b = StringUtils.replace(a, "=", "($%^)");
                msg = StringUtils.replace(msg, a, b);
                msg2 = msg2.substring(idx2, msg2.length());
            }
        }
    }

    private static String getKeyName(String partialMsg) {
        if (partialMsg.startsWith("[") && partialMsg.endsWith("]")) {
            return "";
        } else {
            String character = "";
            String value = "";

            for(int i = partialMsg.length(); i > 0; --i) {
                character = partialMsg.substring(i - 1, i);
                if (character.equalsIgnoreCase(" ")) {
                    return org.apache.commons.lang3.StringUtils.reverse(value);
                }

                value = value + character;
            }

            return "";
        }
    }

    private static String getValue(String partialMsg) {
        partialMsg = org.apache.commons.lang3.StringUtils.removeEnd(partialMsg, getKeyName(partialMsg));
        return partialMsg;
    }

    public static String getNodeText(Object any, String xpath) throws Exception {
        Element element = (Element) XPath.selectSingleNode(any, xpath);
        return element != null ? element.getText() : "";
    }

    public static Element getNode(Object any, String xpath) throws Exception {
        return (Element)XPath.selectSingleNode(any, xpath);
    }
}


